package com.iap.admin.mediator
{
	import com.iap.admin.event.ImageEvent;
	import com.iap.admin.signal.ImageRequestSignal;
	import com.iap.admin.view.vector.VectorImageManagerControl;
	import com.iap.app.AppGlobal;
	import com.iap.app.AppText;
	import com.iap.app.StatusCode;
	import com.iap.app.model.ServiceResponse;
	import com.iap.app.translator.ServiceTranslator;
	import com.iap.app.util.logger.Log;
	import com.iap.common.model.Image;
	import com.iap.common.model.VectorImage;
	import com.iap.common.translator.ImageTranslator;
	
	import flash.events.DataEvent;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.net.URLRequest;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ArrayList;
	import mx.controls.Alert;
	import mx.events.CloseEvent;
	
	import org.osflash.signals.Signal;
	
	import spark.collections.Sort;
	import spark.collections.SortField;
	import com.iap.common.mediator.BaseMediator;

	public class VectorImageManagerControlMediator extends BaseMediator
	{
		[Inject]
		public var view:VectorImageManagerControl;
		[Inject]
		public var request:ImageRequestSignal;

		protected var model:ArrayList;

		protected var file:FileReference;
		
		override public function onRegister():void
		{
			view.onAddButtonClick.add(addHandler);
			view.grid.onRowUp.add(gridRowUp);
			view.grid.onRowDown.add(gridRowDown);
			view.grid.onRemove.add(gridRemoveConfirmation);
			addContextListener(ImageEvent.RESPONSE, responseHandler);
		}
		
		private function addHandler(value:String):void
		{
			if(value == "add")
				browseFile();
		}

		protected function browseFile():void
		{
			file ||= new FileReference();
			addListeners(file);
			file.browse(getTypes());
		}
		
		private function addListeners(dispatcher:IEventDispatcher):void
		{
			dispatcher.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadDataComplete);
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			dispatcher.addEventListener(Event.SELECT, selectHandler);
		}
		
		private function removeListeners(dispatcher:IEventDispatcher):void
		{
			dispatcher.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadDataComplete);
			dispatcher.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			dispatcher.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
			dispatcher.removeEventListener(Event.SELECT, selectHandler);
		}
		
		private function selectHandler(event:Event):void
		{
			sendFile();
		}
		
		public function sendFile():void
		{
			var request:URLRequest = new URLRequest();
			request.url = AppGlobal.FileUploadEndPoint;
			file.upload(request,"file");
		}
		
		private function uploadDataComplete(evt:DataEvent):void
		{
			removeListeners((evt.target as FileReference));
			var serviceRespones:ServiceResponse = ServiceTranslator.translate(evt.data);
			var result:Image = ImageTranslator.translate(serviceRespones.result) as Image;
			view.progressBar.visible = false;
			addItem(result);
			sortGrid();
			view.onImageAdded.dispatch("imageAdded");
		}
		
		private function ioErrorHandler(event:IOErrorEvent):void
		{
			removeListeners(file);
			Log.Info("ioErrorHandler: " + event + " url="+AppGlobal.FileUploadEndPoint);
			view.progressBar.visible = false;
		}
		
		private function progressHandler(event:ProgressEvent):void
		{
			view.progressBar.visible = true;
		}

		protected function getTypes():Array
		{
			var allTypes:Array = new Array(new FileFilter
				(
					"Images (*.jpg; *.jpeg; *.gif; *.png)",
					"*.jpg; *.jpeg; *.gif; *.png; *.tiff; *.tif;"
				));
			return allTypes;
		}

		private function responseHandler(evt:ImageEvent):void
		{
			AppGlobal.endWait();
			if(evt.response.status.code == StatusCode.OK)
			{
				
			}
		}
		
		private function addItem(item:Image):void
		{
			model = new ArrayList(view.grid.dataProvider.toArray());
			var vectorItem:VectorImage = new VectorImage();
			vectorItem.image = item;
			vectorItem.layer = getMaxOrder();
			model.addItem(vectorItem);
			view.grid.dataProvider = model;
			sortGrid();
		}
		
		private function getMaxOrder():int
		{
			var order:int = 0;
			for(var i:uint = 0; i<model.length; i++)
			{
				var item:VectorImage = model.getItemAt(i) as VectorImage;
				if(item.layer > order)
					order = item.layer;
			}
			return order+1;
		}

		private function sortGrid():void
		{
			var list:ArrayCollection = new ArrayCollection(view.grid.dataProvider.toArray());
			var sortOrder:Sort = new Sort();
			sortOrder.fields = [new SortField("sortOrder")];
			list.sort = sortOrder;
			list.refresh();
			view.grid.dataProvider = list;
			cleanSortValue();
			refreshVectorImage();
		}
		
		private function cleanSortValue():void
		{
			var list:ArrayCollection = new ArrayCollection(view.grid.dataProvider.toArray());
			for(var i:uint = 0; i<list.length; i++)
			{
				var item:VectorImage = list[i] as VectorImage;
				item.layer = (i+1);
			}
		}
		
		private function gridGetIndex(data:VectorImage):int
		{
			var index:int = 0;
			var list:ArrayCollection = new ArrayCollection(view.grid.dataProvider.toArray());
			for(var i:uint = 0; i<list.length; i++)
			{
				var item:VectorImage = list.getItemAt(i) as VectorImage;
				if(item.id == data.id)
				{
					index = i;
				}
			}
			return index;
		}
		
		private function gridRowUp(data:VectorImage):void
		{
			var index:int = gridGetIndex(data);
			if(index == 0) return;
			var list:ArrayCollection = new ArrayCollection(view.grid.dataProvider.toArray());
			var item:VectorImage;
			item = list.getItemAt(index-1) as VectorImage;
			item.layer++;
			item = list.getItemAt(index) as VectorImage;
			item.layer--;
			sortGrid();
			updateSortList();
		}
		
		private function gridRowDown(data:VectorImage):void
		{
			var index:int = gridGetIndex(data);
			if(index == view.grid.dataProvider.length-1) return;
			var list:ArrayCollection = new ArrayCollection(view.grid.dataProvider.toArray());
			var item:VectorImage;
			item = list.getItemAt(index+1) as VectorImage;
			item.layer--;
			item = list.getItemAt(index) as VectorImage;
			item.layer++;
			sortGrid();
			updateSortList();
		}

		private function updateSortList():void
		{
			view.onUpdate.dispatch(model.toArray(), "sorted");
		}
		
		private function gridRemoveConfirmation(data:VectorImage):void
		{
			showConfirm(function():void{
				gridRemove(data);
			});
		}

		private function gridRemove(data:VectorImage):void
		{
			var index:int = gridGetIndex(data);
			var list:ArrayCollection = new ArrayCollection(view.grid.dataProvider.toArray());
			list.removeItemAt(index);
			view.grid.dataProvider = list;
			sortGrid();
			request.dispatch(data.image, ImageRequestSignal.DELETE);
		}
		
		private function showConfirm(action:Function):void
		{
			var alert:Alert = Alert.show(AppText.CONFIRM_DELETE, AppText.CONFIRM_DELETE_TITLE, Alert.YES|Alert.NO, null, null, null, Alert.NO);
			var closeFnc:Function;
			alert.addEventListener(CloseEvent.CLOSE, closeFnc = function(evt:CloseEvent):void{
				alert.removeEventListener(CloseEvent.CLOSE, closeFnc);				
				if (evt.detail == Alert.YES)
				{
					action();
				}
			});
		}
		
		private function refreshVectorImage():void
		{
			model = new ArrayList(view.grid.dataProvider.toArray()); 
			view.onUpdate.dispatch(model.toArray(), "refresh");
		}
	}
}